package com.xxchat.controller;

import com.xxchat.annotation.GlobalInterceptor;
import com.xxchat.config.AppConfig;
import com.xxchat.entity.constants.SysConstants;
import com.xxchat.entity.dto.MessageSendDTO;
import com.xxchat.entity.dto.TokenUserInfoDTO;
import com.xxchat.entity.enums.MessageTypeEnum;
import com.xxchat.entity.enums.ResponseCodeEnum;
import com.xxchat.entity.po.ChatMessage;
import com.xxchat.entity.vo.ResponseVO;
import com.xxchat.exception.BusinessException;
import com.xxchat.service.ChatMessageService;
import com.xxchat.service.ChatSessionUserService;
import com.xxchat.utils.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;

@RestController
@RequestMapping("/chat")
public class ChatController extends ABaseController {
    private static final Logger log = LoggerFactory.getLogger(ChatController.class);

    @Resource
    private ChatMessageService chatMessageService;

    @Resource
    private ChatSessionUserService chatSessionUserService;

    @Resource
    private AppConfig appConfig;

    @RequestMapping("/sendMessage")
    @GlobalInterceptor
    public ResponseVO sendMessage(HttpServletRequest request,
                                  @NotEmpty String contactId,
                                  @NotEmpty @Max(500) String content,
                                  @NotNull Integer messageType,
                                  Long fileSize,
                                  String fileName,
                                  Integer fileType) {
        TokenUserInfoDTO userInfoDTO = getTokenUserInfoDTO(request);

        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setContactId(contactId);
        chatMessage.setMessageContent(content);
        chatMessage.setMessageType(messageType);
        chatMessage.setFileSize(fileSize);
        chatMessage.setFileName(fileName);
        chatMessage.setFileType(fileType);

        MessageSendDTO message = this.chatMessageService.saveMessage(chatMessage, userInfoDTO);
        return getSuccessResponseVO(message);
    }

    @RequestMapping("/uploadFile")
    @GlobalInterceptor
    public ResponseVO uploadFile(HttpServletRequest request,
                                 @NotNull Long messageId,
                                 @RequestPart @NotNull MultipartFile file,
                                 @RequestPart MultipartFile cover) {
        TokenUserInfoDTO userInfoDTO = getTokenUserInfoDTO(request);

        this.chatMessageService.saveMessageFile(userInfoDTO.getUserId(), messageId, file, cover);
        return getSuccessResponseVO(null);
    }

    @RequestMapping("/downloadFile")
    @GlobalInterceptor
    public void downloadFile(HttpServletRequest request,
                                   HttpServletResponse response,
                                   @NotEmpty String fileId,
                                   @NotNull Boolean showCover) {
        TokenUserInfoDTO userInfoDTO = getTokenUserInfoDTO(request);
        OutputStream out = null;
        FileInputStream fis = null;
        File file = null;
        try {
            if (!StringTools.isNumber(fileId)) {
                String folderName = SysConstants.FILE_FOLDER_PATH_FILE + SysConstants.FILE_FOLDER_PATH_AVATAR;
                String filePath = appConfig.getProjectFolder() + folderName + fileId + SysConstants.IMAGE_SUFFIX;
                if (showCover) {
                    filePath = appConfig.getProjectFolder() + folderName + fileId + SysConstants.IMAGE_COVER_SUFFIX;
                }
                file = new File(filePath);
                if (!file.exists()) {
                    throw new BusinessException(ResponseCodeEnum.CODE_505);
                }
            } else {
                file = this.chatMessageService.downloadFile(userInfoDTO, fileId, showCover);
            }

            response.setContentType("application/x-msdownload;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;");
            response.setContentLengthLong(file.length());
            fis = new FileInputStream(file);
            out = response.getOutputStream();
            byte[] bytes = new byte[1024];
            int len;
            while ((len = fis.read(bytes)) != -1) {
                out.write(bytes, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            log.error("下载文件失败：{}", e.getMessage(), e);
        } finally {
            if (null != out) {
                try {
                    out.close();
                } catch (Exception e) {
                    log.error("IO异常：{}", e.getMessage(), e);
                }
            }
            if (null != fis) {
                try {
                    fis.close();
                } catch (Exception e) {
                    log.error("IO异常：{}", e.getMessage(), e);
                }
            }
        }
    }
}
